# -*- coding: utf-8 -*-
"""
@Time : 2024/4/2 13:41
@Author : ChenXiaoliang
@Email : middlegod@sina.com
@File : jd_finance.py
"""
import logging
import os
import random
import sys
import time

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys

from get_news import get_news
from publish_article import publish_article
from publish_short import publish_short
from slide import get_slide_track, get_distance, get_bg_slide_img
from valid_phone import valid_phone

LOG_FORMAT = "%(levelname)s %(asctime)s - %(message)s"
logging.basicConfig(filename='jd_finance.log', level=logging.INFO, filemode='a', format=LOG_FORMAT)
logger = logging.getLogger()

# linux driver路径
driver_path = "/usr/bin/chromedriver"
# Win driver路径
#driver_path = "D:\webdriver\chromedriver.exe"

# 京东金融创作者服务平台登录地址
# login_url = "https://creator.jr.jd.com/#/login"
# 嵌套有多个iframes，下面才是真正的登录地址 需要在网页检查中找到最新登录url替换，否则有滑动验证
login_url = 'https://passport.jd.com/common/loginPage?from=biz_jdpay&ReturnUrl=https%3A%2F%2Fpassport.jdpay.com%2Fuser%2FjdLoginCheck.do%3Freturn%3Dhttps%253A%252F%252Fcreator.jr.jd.com%252F%2523%252Fcontent_num%26ticket%3DCZZFWPT-PC'

# 是否无头模式标志head_less
# True-无头模式；False-有头模式
head_less = True
if head_less:
    # 设置无头模式运行选项
    chrome_options = Options()
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--headless")
    # 去掉浏览器上被自动化测试工具控制的标志
    # chrome_options.add_experimental_option('useAutomationExtension', False)
    # chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
    # chrome_options.add_argument("--disable-blink-features=AutomationControlled")
    try:
        driver = webdriver.Chrome(driver_path, options=chrome_options)
    except Exception as err:
        logger.error(f"创建浏览器对象失败，报错：{err}")
        sys.exit(f"无头模式下，创建浏览器对象失败{err}，退出程序执行！")
else:
    chrome_options = Options()
    # 以下3个选项配置用于去掉浏览器上被自动化测试工具控制的标志
    chrome_options.add_experimental_option('useAutomationExtension', False)
    chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
    chrome_options.add_argument("--disable-blink-features=AutomationControlled")
    try:
        driver = webdriver.Chrome(driver_path, options=chrome_options)
    except Exception as err:
        logger.error(f"创建浏览器对象失败，报错：{err}")
        sys.exit(f"有头模式下，创建浏览器对象失败，{err},退出程序执行！")

driver.maximize_window()
# 打开登录页面
driver.get(login_url)

# 打开登录页面，等待10s
time.sleep(5)

# 找到登录用户输入框，并输入
login_user = driver.find_element_by_id("loginname")
logger.info(f"成功找到登录用户输入框：{login_user}")
user = os.environ.get('JD_USER')
login_user.send_keys(user)
login_user.send_keys(Keys.ENTER)
time.sleep(2)
# 找到登录密码输入框，并输入
login_pw = driver.find_element_by_id("nloginpwd")
logger.info(f"成功找到登录密码输入框：{login_pw}")
pw = os.environ.get('JD_PW')
login_pw.send_keys(pw)
login_pw.send_keys(Keys.ENTER)

time.sleep(1)
# 找到登录按钮，并点击
logger.info("开始登录")
login_btn = driver.find_element_by_id("paipaiLoginSubmit")
logger.info(f"成功找到登录按钮：{login_btn}")
driver.execute_script("arguments[0].click()", login_btn)
logger.info("已点击登录！")
time.sleep(1)

# 处理滑动验证
get_bg_slide_img(driver)
slider = driver.find_element_by_class_name("JDJRV-slide-btn")
# 获取滑动距离
dis = get_distance()
print("滑动距离：", dis)
time.sleep(1)
# 执行滑块滑动动作
act = ActionChains(driver)
act.click_and_hold(slider).perform()
time.sleep(1)
for i in get_slide_track(dis):
    logger.info(f"滑动距离：{i}")
    act.move_by_offset(i, random.randrange(1, 3))
act.release().perform()
driver.get_screenshot_as_file("login_or_not_1.png")

time.sleep(20)
# 可能需要手机号验证
try:
    valid_phone(driver)
    driver.get_screenshot_as_file("valid_phone_success.png")
except Exception as err:
    driver.get_screenshot_as_file("valid_phone_occur_error.png")
    logger.error(f"手机号验证过程中报错：{err}")
    sys.exit("手机号验证过程中报错，退出程序执行！！！")

"""以上为登录操作，接下来进行具体的发布操作"""
time.sleep(20)
driver.get_screenshot_as_file("login_or_not_2.png")

# 验证是否登录成功
try:
    page_side = driver.find_element_by_class_name("page-aside")
    if page_side:
        driver.get_screenshot_as_file("login_success.png")
        logger.info("滑动验证通过，登录成功！！！")
    else:
        logger.error("未找到page sider，可能登录失败~")
except Exception as err:
    driver.get_screenshot_as_file("no_page_sider.png")
    logger.error(f"未找到page sider，登录失败，程序退出执行！！！报错：{err}")
    sys.exit("未找到page sider，登录失败，程序退出执行！！！")

"""以上为判断登录是否成功"""
"""以上为登录的一系列操作，接下来进行具体的发布操作"""

# 长时间监控发布标志
on = True
while on:
    try:
        news = get_news()
        logger.info(f"{news[0]['title']}")

        for new in news:
            # 获取新闻标题
            new_title = new['title']
            # 根据新闻标题判断是否包含特定关键字
            publish_condition = "收评" in new_title or "上午复盘" in new_title or "午间收评" in new_title

            # 如果标题中含有中文冒号：,根据中文冒号分隔列表取第一个元素
            new_title_first = new_title.split("：")[0]
            # 判断是否已经发布
            with open("published_news.txt", "r", encoding='utf-8') as pub_new:
                # 是否已经发布 True-未包含；False-包含
                content = pub_new.read()
                publish_status = new_title not in content
                new_title_first_exclude = new_title_first not in content

            if publish_condition and publish_status and new_title_first_exclude:
                publish_article(driver, new)

            """以下是 短动态的发布操作"""
            short_new_condition = "整点回顾" in new_title or "中概指数" in new_title or "金龙" in new_title
            with open("published_news.txt", "r", encoding='utf-8') as pub_new:
                # 是否已经发布 True-未包含；False-包含
                content = pub_new.read()
                publish_status = new_title not in content
            if short_new_condition and publish_status:
                publish_short(driver, new)

        # 定时刷新下页面
        driver.refresh()
        time.sleep(60 * 10)
    except Exception as err:
        logger.error(f"最外层的报错，报错信息：{err}")
